<template>
  <el-page-header class="head" :icon="null" title="云手机平台">
    <template #content>
      <div><span>单实例云手机</span></div>
    </template>
    <template #extra>
      <div>
        <el-button @click="exitPhone" type="danger">退出云手机</el-button>
      </div>
    </template>
  </el-page-header>
  <div class="wallpaper" :id="fullscreenContainer" v-loading="loading">
    <div class="phone-message">
      <div>
        时延： <span style="color: #1476ff">{{ delayTime }} </span>ms
      </div>
    </div>
    <div
      class="phone-wallpaper"
      :style="{
        flexDirection: rotatePlayerClass === 'PORTRAIT' ? 'row' : 'column',
      }"
    >
      <div class="fullscreen-container">
        <div
          :id="phoneContainer"
          :class="rotatePlayerClass"
          class="phone-container"
        ></div>
      </div>
      <div
        v-show="controlVisible"
        class="phone-control"
        :class="phoneControlClass"
      >
        <el-tooltip effect="dark" content="返回" placement="right-start">
          <el-button @click="back" style="margin: 0" :icon="Back" circle>
          </el-button>
        </el-tooltip>
        <el-tooltip effect="dark" content="桌面" placement="right-start">
          <el-button @click="home" style="margin: 0" :icon="HomeFilled" circle>
          </el-button>
        </el-tooltip>
        <el-tooltip effect="dark" content="多任务" placement="right-start">
          <el-button @click="menu" style="margin: 0" :icon="Grid" circle>
          </el-button>
        </el-tooltip>
        <el-tooltip effect="dark" content="全屏" placement="right-start">
          <el-button
            @click="fullScreen"
            style="margin: 0"
            :icon="FullScreen"
            circle
          >
          </el-button>
        </el-tooltip>
      </div>
    </div>
    <div class="phone-panel"></div>
  </div>
</template>

<script lang="ts">
import { HomeFilled, Grid, Back, FullScreen } from '@element-plus/icons-vue';
import { ref } from 'vue';
import CPHCloudApp from '../static/CPHCloudApp';
import { ElMessageBox } from 'element-plus';
export default {
  setup() {
    const commonLibPath = ref(null);
    const loading = ref(false);
    const controlVisible = ref(false);
    const delayTime = ref(0);
    const rotatePlayerClass = ref('PORTRAIT');
    const phoneControlClass = ref('PORTRAIT');
    const hasAlertModal = ref(false);
    return {
      HomeFilled,
      Grid,
      Back,
      FullScreen,
      hasAlertModal,
      controlVisible,
      loading,
      commonLibPath,
      rotatePlayerClass,
      phoneControlClass,
      ip: '',
      port: '',
      delayTime,
      isUserLogin: false,
      phoneContainer: 'phone-container',
      fullscreenContainer: 'fullscreen-container',
    };
  },
  created() {
    this.commonLibPath = window.location.origin + '/lib/';

    // 从url中获取ip和port
    this.ip = JSON.parse(sessionStorage.getItem('cloudPhoneHost')).ip;
    this.port = JSON.parse(sessionStorage.getItem('cloudPhoneHost')).port;
  },
  mounted() {
    // H5测试直连
    this.connectCloudPhone();
  },
  methods: {
    connectCloudPhone() {
      let that = this;
      let cloudPhoneParams;
      var cloudPhoneHost = JSON.parse(sessionStorage.getItem('cloudPhoneHost'));
      var channelType = sessionStorage.getItem('channelType');
      if (cloudPhoneHost) {
        this.isUserLogin = false;
        // 测试直连
        var cloudIp = cloudPhoneHost['ip'];
        var cloudPort = cloudPhoneHost['port'];
        cloudPhoneParams = {
          ip: cloudIp,
          port: cloudPort,
          session_id: this.uuid_32(),
          background_timeout: '0', // 后台运行超时时间
          available_playtime: '0', // 试玩时间
          touch_timeout: 0, // 未触控超时时间
          connect_uri: 'wss://' + [cloudIp, cloudPort].join(':'),
        };
      } else {
        this.$router.push('/login');
      }

      const params = {
        ...cloudPhoneParams,
        channelType: channelType,
        ticket: '256random'.padStart(256, '0'),
        auth_ts: new Date().getTime(), // 时间戳 timestamp
        aes_key: '',
        _debug: true,
        auto_rotate: true,
        libPath: this.commonLibPath, // 配置库文件地址
        microPhoneOutputType: 'OPUS', // PCM或OPUS
        fullscreenId: this.fullscreenContainer, // 全屏DOM ID
      };
      if (CPHCloudApp.isSupport()) {
        const cloudapp = new CPHCloudApp(this.phoneContainer, params);
        cloudapp.on('appStateChange', function (event, data) {
          console.log(event, data);
          var state = data && data.state;
          var STATE_CONFIG = {
            STARTED: 2048,
            RESUMED: 5120,
            MEDIA_CONFIG_SUCCESS: 8448,
            RETRY_SUCCESS: 3072,
            BACK_HOME: 6400,
          };

          var normalStates = [
            STATE_CONFIG.STARTED,
            STATE_CONFIG.RESUMED,
            STATE_CONFIG.MEDIA_CONFIG_SUCCESS,
            STATE_CONFIG.BACK_HOME,
            STATE_CONFIG.RETRY_SUCCESS,
          ];
          that.loading = !normalStates.includes(state);
          that.showAlertModal(data);
          that.startsuccessCallBack(data);
        });

        cloudapp.on('netStateChange', function (event: any, data: any) {
          that.delayTime = data.delay;
        });

        // 音量设置，范围为 0 ~ 100
        cloudapp.setVolume(60);

        cloudapp.on('audioStateChange', function (event: any, data: any) {
          console.log(event, data);
        });

        cloudapp.on('cloudAppData', function (event, data) {
          var typedArray = new Uint8Array(data);
          var str = this.decodeUTF8(typedArray);
          console.log(event, str);
        });

        cloudapp.on('rotatePlayer', function (event: any, data: any) {
          that.rotatePlayerClass =
            data.orientation === 'PORTRAIT' ? 'PORTRAIT' : 'LANDSCAPE';
          that.phoneControlClass =
            data.orientation === 'PORTRAIT'
              ? 'phone-ontrol-PORTRAIT'
              : 'phone-control-LANDSCAPE';
        });

        window.cloudapp = cloudapp;
        window.sendDataToCloudApp = function (str) {
          var utf8Array = this.encodeUTF8(str);
          var typedArray = new Uint8Array(utf8Array);
          window.cloudapp.sendDataToCloudApp(typedArray.buffer);
        };

        this.listenLocationReload();

        // 监听云机复制内容写入端侧粘贴板
        cloudapp.on('clipboardDataChange', function (event, data) {
          var save = function (e) {
            e.clipboardData.setData('text/plain', data);
            e.preventDefault();
          };
          document.addEventListener('copy', save);
          document.execCommand('copy');
          document.removeEventListener('copy', save);
        });

        // 监听端侧粘贴，获取粘贴板内容发给云机
        document.addEventListener('paste', event => {
          const pasteContent = event.clipboardData.getData('text/plain');
          cloudapp.sendClipboardData(pasteContent);
        });
      }
    },

    showAlertModal(data) {
      const startSuccessState = 512;
      // 连接成功需要关闭已显示的弹框
      if (data.state === startSuccessState && this.hasAlertModal) {
        ElMessageBox.close();
        this.hasAlertModal = false;
        return;
      }
      if (data.tip && !this.hasAlertModal) {
        this.hasAlertModal = true;
        ElMessageBox.confirm(data.tip, '提示', {
          closeOnPressEscape: false,
          closeOnClickModal: false,
          showClose: false,
          cancelButtonText: '退出',
          confirmButtonText: '重试',
        })
          .then(() => {
            window.cloudapp.exit();
            this.connectCloudPhone();
          })
          .catch(() => {
            this.exitPhone();
          });
      }
    },

    startsuccessCallBack(data) {
      const connectSuccessState = 2048;
      if (data.state === connectSuccessState) {
        this.controlVisible = true;
      }
    },

    decodeUTF8(utf8Array, start, end) {
      var len = utf8Array.length;
      start = start || 0;
      end = end || len;
      if (start < 0 || start >= len || end < 0 || end > len) {
        return '';
      }

      var encodedStr = '';
      for (var i = start; i < end; i++) {
        encodedStr += '%' + utf8Array[i].toString(16);
      }

      return decodeURIComponent(encodedStr);
    },

    encodeUTF8(textStr) {
      var encodedStr = encodeURIComponent(textStr);
      var encodedArray = [];
      for (var i = 0; i < encodedStr.length; i++) {
        var cur = encodedStr.charAt(i);
        if (cur === '%') {
          var code = encodedStr.charAt(i + 1) + encodedStr.charAt(i + 2);
          encodedArray.push(parseInt(code, 16));
          i += 2;
        } else {
          encodedArray.push(cur.charCodeAt(0));
        }
      }
    },

    listenLocationReload() {
      document.addEventListener('visibilitychange', () => {
        const isFirstTrust = sessionStorage.getItem('isFirstTrust');
        if (document.visibilityState === 'visible' && isFirstTrust === 'true') {
          location.reload();
          sessionStorage.setItem('isFirstTrust', 'false');
        }
      });
    },

    exitPhone() {
      window.cloudapp.exit();
      sessionStorage.removeItem('cloudPhoneHost');
      this.$router.push('/login');
    },

    uuid_32() {
      let uuid = '';
      for (let i = 0; i < 26; i++) {
        uuid += Math.floor(Math.random() * 10);
      }
      return uuid + '32uuid';
    },

    home() {
      window.cloudapp.home();
    },
    menu() {
      window.cloudapp.menu();
    },
    back() {
      window.cloudapp.back();
    },
    fullScreen() {
      window.cloudapp.fullscreenToggle(this.fullscreenContainer);
    },
  },
};
</script>
<style scoped lang="less">
@media screen and (min-width: 720px) {
  .head {
    padding: 20px;
    :deep(.el-page-header__title) {
      color: var(--el-text-color-primary);
      font-size: 18px;
    }
  }

  .wallpaper {
    height: calc(100vh - 72px);
    width: 100%;
    display: flex;
    justify-content: space-between;
    background: radial-gradient(
      circle at 5px 5px,
      var(--el-fill-color-dark) 2px,
      #f2f6fc 0
    );
    background-size: 25px 25px;
  }

  .phone-message {
    width: 240px;
    height: 80px;
    padding: 10px 15px;
    margin: 5px 0 0 5px;
    background-color: #fff;
    border: 1px solid var(--el-border-color);
    border-radius: 10px;
    box-shadow: var(--el-box-shadow);
    > span {
      font-weight: 800;
    }
  }

  .phone-wallpaper {
    margin: auto;
    display: flex;
    align-items: center;
    justify-content: space-between;
    .fullscreen-container {
      display: flex;
    }
  }

  .phone-container {
    overflow: hidden;
    background-color: #fff;
    box-shadow: var(--el-box-shadow);
    border: 1px solid var(--el-border-color);
    border-radius: var(--el-border-radius-round);
  }

  .PORTRAIT {
    width: 45rem;
    height: 80rem;
  }

  .LANDSCAPE {
    width: 56rem;
    height: 100rem;
  }

  .phone-control {
    display: flex;
    background-color: #fff;
    padding: 0 7.5px;
    margin-left: 2.5rem;
    box-shadow: var(--el-box-shadow);
    border: 1px solid var(--el-border-color);
    border-radius: var(--el-border-radius-round);
  }

  .phone-ontrol-PORTRAIT {
    height: 25rem;
    flex-direction: column;
    align-items: center;
    justify-content: space-around;
  }

  .phone-control-LANDSCAPE {
    position: relative;
    top: -16rem;
    width: 24rem;
    height: 4rem;
    justify-content: space-around;
    align-items: center;
  }

  .phone-panel {
    width: 240px;
  }
}

@media screen and (max-width: 720px) {
  .head {
    display: none;
    padding: 20px;
    :deep(.el-page-header__title) {
      color: var(--el-text-color-primary);
      font-size: 18px;
    }
  }

  .wallpaper {
    height: 100%;
    width: 100%;
    display: flex;
    justify-content: space-between;
    background: radial-gradient(
      circle at 5px 5px,
      var(--el-fill-color-dark) 2px,
      #f2f6fc 0
    );
    background-size: 25px 25px;
  }

  .phone-message {
    display: none;
  }

  .phone-wallpaper {
    margin: auto;
    display: flex;
    align-items: center;
    justify-content: space-between;
    .fullscreen-container {
      display: flex;
    }
  }

  .phone-container {
    background-color: #fff;
    box-shadow: var(--el-box-shadow);
    border: 1px solid var(--el-border-color);
    border-radius: var(--el-border-radius-round);
  }

  .phone-control {
    display: none;
  }

  .phone-panel {
    display: none;
  }

  .PORTRAIT {
    width: 100vw;
    height: 100vh;
  }

  .LANDSCAPE {
    width: 100vw;
    height: 100vh;
  }
}
</style>
